#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "debug.h"
#include "os_api.h"
#include "ps_api.h"
#include "dev_api.h"
#include "mqttclient.h"
#include "os_api.h"
#include "debug.h"
#include "hal/gpio.h"
#include "lpconfig.h"

extern void atcmds_register_init(void);

int mqtt_send_msg(uint32_t msgId, void *data);



#define mqtt_cmd_wakeup_GPIO        4       // 选择一个GPIO用于唤醒主控

#define WAKUP_TOPIC_NAME    "/wakeup/topic"

#define MQTT_STACK_SIZE	(1024*3)

static void* mqtt_task_stack = NULL;

static OSTaskRef mqtt_task_ref = NULL;

typedef struct _MqttMessage
{
	UINT32		msgId;
	void*		data;
}MqttMessage;

static OSMsgQRef mqttTaskMsgQ = NULL;

static mqtt_client_t *client = NULL;


void mqtt_wakeup(void)
{
    lp_wakeup();
}

void mqtt_sleep(void)
{
    lp_sleep();
}


static void sub_topic_handle1(void *client, message_data_t *msg)
{
    LOG_PRINTF("-----------------------------------------------------------------------------------");
    LOG_PRINTF("%s:%d %s()...\ntopic: %s\nmessage:%s", __FILE__, __LINE__, __FUNCTION__, msg->topic_name, (char *)msg->message->payload);
    LOG_PRINTF("-----------------------------------------------------------------------------------");

    if (strcmp(msg->topic_name, WAKUP_TOPIC_NAME) == 0){
        // 唤醒主控，并禁止模块休眠
        mqtt_send_msg(MQTT_CMD_WAKEUP, NULL);
    }
}

void wait_network_ready(void)
{
    int count = 30;
    while(count-- && ps_GetNetworkReady() == FALSE){	
        OSATaskSleep(200);
    }

    if (count <= 0){
        LOG_PRINTF("dev_CtrlReset.\n");
        dev_CtrlReset(0);
    }
}

void mqtt_cmd_start(void)
{
    int rc = -1;
    char portstring[32] = {0};
    lpSetCfg *cfg = getLpCfgInfo();

    LOG_PRINTF("%s()... mqtt test begin...", __FUNCTION__);

    // 进入休眠 // 其实是允许模块进入休眠，
    mqtt_sleep();

    if (client != NULL){
        if (client->mqtt_client_state == CLIENT_STATE_CONNECTED) {
            return;
        } else {
            mqtt_disconnect(client);
            mqtt_release(client);
            client = NULL;
        }
    }
    client = mqtt_lease();

    mqtt_set_host(client, cfg->hostname);
    sprintf(portstring, "%d", cfg->port);
    mqtt_set_port(client, portstring);
    mqtt_set_client_id(client, cfg->mqtt_clientid);
	mqtt_set_user_name(client, cfg->mqtt_username);
	mqtt_set_password(client, cfg->mqtt_password);
    mqtt_set_clean_session(client, 1);
	
    rc = mqtt_connect(client);	
    LOG_PRINTF("%s() mqtt_connect rc code:%d", __FUNCTION__, rc);

    rc = mqtt_subscribe(client, WAKUP_TOPIC_NAME, QOS0, sub_topic_handle1);
    LOG_PRINTF("%s() mqtt_subscribe rc code:%d", __FUNCTION__, rc);
    if(rc != 0){
        mqtt_release(client);
        client = NULL;
        // mqtt 连接失败，唤醒
        mqtt_wakeup();
    }
}

void mqtt_cmd_stop(void)
{
    int rc = -1;
    int count = 5;

    if (client == NULL)
        return;
    rc = mqtt_disconnect(client);
    LOG_PRINTF("%s() mqtt_disconnect rc code:%d", __FUNCTION__, rc);

	while(count-- && client && client->mqtt_client_state == CLIENT_STATE_CONNECTED){
		OSATaskSleep(20);
	}
	if (client){
		mqtt_release(client);
		client = NULL;
	}
}


void mqtt_cmd_wakeup(void)
{
    mqtt_wakeup();
}

void mqtt_cmd_sleep(void)
{
    mqtt_sleep();
}

void mqtt_task(void *ptr)
{
    int count = 0;
    OS_STATUS  status;
    MqttMessage mqttMsg = {0};

    while (1)
    {
        status = OSAMsgQRecv(mqttTaskMsgQ, (void *)&mqttMsg, sizeof(MqttMessage), 30*200/*OSA_SUSPEND*/);  //30秒检测一次
        // 正常接接收MQTTtask的消息
        if (status == OS_SUCCESS){
            LOG_PRINTF("%s() mqttMsg.msgId: %d", __FUNCTION__, mqttMsg.msgId);
            switch (mqttMsg.msgId) {
                case MQTT_CMD_START:
                    mqtt_cmd_start();
                    break;
                case MQTT_CMD_STOP:
                    mqtt_cmd_stop();
                    break;
                case MQTT_CMD_SLEEP:
                    mqtt_cmd_sleep();
                    break;
                case MQTT_CMD_WAKEUP:
                    mqtt_cmd_wakeup();
                    break;
                default:
                    break;
            }            
        }
        //30秒检测一次MQTT状态
        else if (status == OS_TIMEOUT){
            if (client == NULL)
                continue;
            if (client->mqtt_client_state == CLIENT_STATE_CONNECTED) {
                count = 0;
            } else {
                count++;
                if (count >=3) {
                    mqtt_disconnect(client);
                    mqtt_release(client);
                    client = NULL;
                    mqtt_cmd_wakeup();
                }
            }
        } else {
            ASSERT(0);
        }
    }
}

int mqtt_send_msg(uint32_t msgId, void *data)
{
    MqttMessage msg = {0};

    msg.msgId = msgId;
    msg.data = data;

    if (OS_SUCCESS == OSAMsgQSend(mqttTaskMsgQ, sizeof(MqttMessage), (UINT8 *)&msg, OSA_NO_SUSPEND)) {
        return 0;
    }
    
    return -1;
}

void lqmqtt_main(void)
{	
	int ret;

    /*creat message*/
    ret = OSAMsgQCreate(&mqttTaskMsgQ, "mqttTaskMsgQ", sizeof(MqttMessage), 30, OS_FIFO);
    ASSERT(ret == OS_SUCCESS);

	mqtt_task_stack = malloc(MQTT_STACK_SIZE);
	ASSERT(mqtt_task_stack != NULL);
	
    ret = OSATaskCreate(&mqtt_task_ref, mqtt_task_stack, MQTT_STACK_SIZE, 100, "mqtt_task", mqtt_task, NULL);
    ASSERT(ret == OS_SUCCESS);
}
